package com.robusta.cityuate.activities;

import java.io.IOException;
import java.util.List;
import java.util.Locale;

import android.content.Context;
import android.content.Intent;
import android.graphics.drawable.Drawable;
import android.location.Address;
import android.location.Geocoder;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.Toast;

import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapController;
import com.google.android.maps.MapView;
import com.google.android.maps.MyLocationOverlay;
import com.google.android.maps.Overlay;
import com.google.android.maps.OverlayItem;
import com.robusta.cityuate.R;
import com.robusta.cityuate.base.CityuateItemizedOverlay;
import com.robusta.cityuate.base.CityuateMapActivity;
import com.robusta.cityuate.services.DBClass;
import com.robusta.cityuate.services.LocationService;

//this class is responsible for creating a new reminder
public class CreateReminderActivity extends CityuateMapActivity{
	// all the needed attributes
	private Geocoder gc;
	private LocationManager locationManager;
	private MapView mapView;
	private MapController mapController;
	private MyLocationOverlay myLocationOverlay;
	private List<Overlay> mapOverLay;
	private EditText longitude;
	private EditText latitude;
	private Button remindMe;
	private ImageButton reset;
	private CityuateItemizedOverlay itemizedOverlay;
	private Drawable drawable;
	private String address;
	private Handler h;
	protected OverlayItem item;
	private EditText comment;
	private Context mContext = this;

	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.create_reminder_view);
		mapView = (MapView) findViewById(R.id.map_view);
		longitude = (EditText) findViewById(R.id.remind_long);
		latitude = (EditText) findViewById(R.id.remind_lat);
		comment = (EditText) findViewById(R.id.remind_comment);
		remindMe = (Button) findViewById(R.id.remind_me);
		remindMe.setOnClickListener(new OnClickListener() {
			// inserting a reminder into database and start a service if not
			// working
			@Override
			public void onClick(View arg0) {
				if ((!longitude.getText().toString().equals(""))
						&& (!latitude.getText().toString().equals(""))) {
					// why not we create this method in each Object !! GAD
					String[] values = {
							address,
							longitude.getText().toString(),
							latitude.getText().toString(),
							comment.getText().toString().equals("") ? "No comment"
									: comment.getText().toString() };
					DBClass.InsertIntoTable(CreateReminderActivity.this,
							DBClass.TABLE_NAME_REMINDER, values);
					Intent intent = new Intent(
							CreateReminderActivity.this,
							LocationService.class);
					startService(intent);
					finish();
				} else {
					Toast.makeText(arg0.getContext(), "please fill all fields",
							Toast.LENGTH_LONG).show();
				}

			}

		});

		reset = (ImageButton) findViewById(R.id.reset);
		reset.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View arg0) {

				if (myLocationOverlay.getMyLocation() != null)
					mapController.animateTo(myLocationOverlay.getMyLocation());
				else
					Toast.makeText(mContext, R.string.location_unavailable,
							Toast.LENGTH_SHORT).show();
			}

		});

		//mapView.setStreetView(true);
		mapController = mapView.getController();
		mapController.setZoom(14);
		myLocationOverlay = new MyLocationOverlay(this, mapView) {
			// add a bubble on the screen and get is coordinate from the map
			@Override
			public boolean onTap(GeoPoint p, MapView map) {
				longitude.setText((double) (p.getLongitudeE6() / 1000000.0)
						+ "");
				latitude.setText((double) (p.getLatitudeE6() / 1000000.0) + "");
				itemizedOverlay.removeAll();
				itemizedOverlay.hideAllBalloons();
				address = "";
				// getting the address in a new thread.
				Thread t = new Thread() {
					public void run() {
						address = updateMyAddress(Double.parseDouble(longitude
								.getText().toString()),
								Double.parseDouble(latitude.getText()
										.toString()));
						h.sendEmptyMessage(0);
					}
				};
				t.start();
				item = new OverlayItem(p, "Reminder", address);
				itemizedOverlay.addOverlay(item);
				return super.onTap(p, map);
			}
		};
		// needed to update view from another thread other than the main.
		h = new Handler() {
			@Override
			public void handleMessage(Message msg) {
				itemizedOverlay.removeAll();
				item = new OverlayItem(item.getPoint(), item.getTitle(),
						address);
				itemizedOverlay.addOverlay(item);
			}
		};
		// map adjustment + running the gps
		mapView.displayZoomControls(false);
		mapOverLay = mapView.getOverlays();
		mapOverLay.add(myLocationOverlay);
		myLocationOverlay.enableCompass();
		myLocationOverlay.enableMyLocation();
		drawable = getResources().getDrawable(R.drawable.marker);
		itemizedOverlay = new CityuateItemizedOverlay(drawable, mapView);
		mapOverLay.add(itemizedOverlay);
		gc = new Geocoder(this, Locale.getDefault());
		locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
		locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0,
				0, new GeoUpdateHandler());
		if (locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER) == null) {
			locationManager.requestLocationUpdates(
					LocationManager.NETWORK_PROVIDER, 0, 0,
					new GeoUpdateHandler());
		}

	}

	public class GeoUpdateHandler implements LocationListener {

		@Override
		public void onLocationChanged(Location location) {
			// mapController.animateTo(myLocationOverlay.getMyLocation());
		}

		@Override
		public void onProviderDisabled(String provider) {
		}

		@Override
		public void onProviderEnabled(String provider) {
		}

		@Override
		public void onStatusChanged(String provider, int status, Bundle extras) {

		}
	}

	@Override
	protected boolean isRouteDisplayed() {
		return false;
	}

	// getting the address as string
	public String updateMyAddress(double longitude, double latitude) {
		Location location = new Location(LocationManager.NETWORK_PROVIDER);
		location.setLatitude(latitude);
		location.setLongitude(longitude);
		double distance = 0.0;
		if (locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER) != null) {
			distance = locationManager.getLastKnownLocation(
					LocationManager.GPS_PROVIDER).distanceTo(location);
		} else {
			distance = locationManager.getLastKnownLocation(
					LocationManager.NETWORK_PROVIDER).distanceTo(location);
		}
		Address yourAddress = null;
		try {
			yourAddress = (getAddressForLocation(this, location));

		} catch (Exception e) {

			e.printStackTrace();
		}
		StringBuilder sb = new StringBuilder();
		if (yourAddress != null) {
			for (int i = 0; i < yourAddress.getMaxAddressLineIndex(); i++) {
				if (i + 1 == yourAddress.getMaxAddressLineIndex()) {
					sb.append(yourAddress.getAddressLine(i));
				} else {
					sb.append(yourAddress.getAddressLine(i) + ",");
				}

			}
			String mylocation = sb.toString();
			if (mylocation.length() == 0) {
				return "No Address";
			}
			String temp = distance / 1000 + "";
			if (temp.length() >= 7) {
				temp = temp.substring(0, 7);
			}
			return mylocation + "\n" + temp + "Km";
		} else {
			return "No Address";
		}

	}

	// A helper method for updating the address.
	public Address getAddressForLocation(Context context, Location location)
			throws IOException {

		if (location == null) {
			return null;
		}
		double latitude = location.getLatitude();
		double longitude = location.getLongitude();
		int maxResults = 5;
		List<Address> addresses = gc.getFromLocation(latitude, longitude,
				maxResults);

		if (addresses.size() == 0) {
			return null;
		}
		return addresses.get(0);

	}

}